import { _decorator, Component, JsonAsset, Node, Scheduler, sys } from 'cc';
import { Weapon } from './Weapon';
import { BULLET, CAPACITY, PROPS, WEAPON, WEAPONTYPE } from '../AshFramework/Datas/Constant';
import { ZTool } from '../AshFramework/Utils/ZTool';
import { ResourceUtil } from '../AshFramework/Utils/ResourceUtil';
import { Gun } from './Gun';
import { Bullet } from './Bullet';
import { PrefsManager } from '../AshFramework/Managers/PrefsManager';
const { ccclass, property } = _decorator;

@ccclass('GameData')
export class GameData {
    private static _instance: GameData = null;
    public static get Instance(): GameData {
        if (!this._instance) {
            this.ReadDate();
            this.autoSave();
        }
        return this._instance;
    }
    public GunData: { [key: string]: Weapon | null } = {
    }

    public BulletData: { [key: string]: Bullet } = {
    }

    public PropsData: { [key: string]: number } = {
        "药丸": 0,
        "参考答案": 0,
        "咖啡": 0,
    }
    public static DateSave() {
        let json = JSON.stringify(GameData.Instance);
        sys.localStorage.setItem("TLWLSJ_GAMEDATA", json);
        console.log("游戏存档");
    }

    public static ReadDate() {
        let name = sys.localStorage.getItem("TLWLSJ_GAMEDATA");
        if (name != "" && name != null) {
            console.log("读取存档");
            GameData._instance = Object.assign(new GameData(), JSON.parse(name));
        } else {
            console.log("新建存档");
            GameData._instance = new GameData();
        }
    }

    public static getWeaponByName(WeaponName: string): Weapon | null {
        // const name: string = ZTool.GetEnumKeyByValue(WEAPON, weapon);
        if (!GameData.Instance.GunData[WeaponName]) {
            return null;
        }
        return GameData.Instance.GunData[WeaponName]
    }

    public static addWeaponByType(type: WEAPON) {
        const name: string = ZTool.GetEnumKeyByValue(WEAPON, type);
        GameData.addWeaponByName(name);
    }

    public static addWeaponByName(name: string) {
        if (!GameData.Instance.GunData[name]) {
            ResourceUtil.LoadJson("WeaponData").then((jsonAsset: JsonAsset) => {
                const json = jsonAsset.json[name];

                if (json.type == WEAPONTYPE.MELEE) {
                    console.log(`添加近战武器：${name}`);
                    GameData.Instance.GunData[name] = new Weapon(json.type, json.harm, json.coolingTime, json.armorPenetration);
                } else if (json.type == WEAPONTYPE.RANGED) {
                    console.log(`添加远程武器：${name}`);
                    const capacity: number = CAPACITY[name];
                    GameData.Instance.GunData[name] = new Gun(json.type, json.harm, json.coolingTime, json.armorPenetration, capacity);
                }
                if (name === "破片手雷") {
                    PrefsManager.Instance.userData.HaveWeapon.push(WEAPON.破片手雷);
                } else if (name === "高爆手雷") {
                    PrefsManager.Instance.userData.HaveWeapon.push(WEAPON.高爆手雷);
                }
                GameData.DateSave();
                PrefsManager.Instance.saveData();
            })
        }
    }

    public static loseWeaponByName(name: string) {
        if (GameData.Instance.GunData[name]) {
            delete GameData.Instance.GunData[name];
            PrefsManager.Instance.userData.HaveWeapon.splice(PrefsManager.Instance.userData.HaveWeapon.indexOf(WEAPON[name]), 1);
            PrefsManager.Instance.saveData();
            GameData.DateSave();
        }
    }

    public static addBulletByType(type: BULLET, num: number = 1) {
        const name: string = ZTool.GetEnumKeyByValue(BULLET, type);
        GameData.addBulletByName(name, num);
    }

    public static addBulletByName(name: string, num: number = 1) {
        if (!GameData.Instance.BulletData[name]) {
            //创建子弹
            ResourceUtil.LoadJson("AmmoData").then((jsonAsset: JsonAsset) => {
                const json = jsonAsset.json[name];
                let belongTo: WEAPON[] = [];
                const keys: string[] = json.belongTo;
                for (let index = 0; index < keys.length; index++) {
                    const key = keys[index];
                    belongTo.push(WEAPON[key]);
                }
                GameData.Instance.BulletData[name] = new Bullet(name, belongTo, json.harm, json.armorPenetration, num);
                GameData.DateSave();
            })
            if (name === "破片手雷" || name === "高爆手雷") {
                GameData.addWeaponByName(name);
            }
        } else {
            GameData.Instance.BulletData[name].Count += num;
        }
        GameData.DateSave();
    }

    /**
     * 使用子弹
     * @param name 子弹名称
     * @param num 使用子弹数量
     * @returns 使用子弹之后子弹数量是否大于0
     */
    public static subBulletByName(name: string, num: number = 1): boolean {
        if (GameData.Instance.BulletData[name]) {
            GameData.Instance.BulletData[name].Count -= num;
            if (GameData.Instance.BulletData[name].Count <= 0) {
                delete GameData.Instance.BulletData[name];
                // if (name === "破片手雷" || name === "高爆手雷") {
                //     GameData.loseWeaponByName(name);
                // }
                return false;
            }
        }
        GameData.DateSave();
        return true;
    }


    public static getBulletNumByName(name: string) {
        if (!GameData.Instance.BulletData[name]) {
            return 0;
        } else {
            return GameData.Instance.BulletData[name].Count;
        }
    }

    public static getBulletByWeapon(weapon: WEAPON): Bullet[] {
        const result: Bullet[] = [];
        for (const name in GameData.Instance.BulletData) {
            if (GameData.Instance.BulletData[name].BelongTo.findIndex(e => e == weapon) != -1) {
                result.push(GameData.Instance.BulletData[name]);
            }
        }
        return result;
    }

    public static addPropByType(type: PROPS, num: number = 1) {
        const name: string = ZTool.GetEnumKeyByValue(PROPS, type);
        if (GameData.Instance.PropsData[name] == undefined) {
            console.error(`没有该道具！`);
        } else {
            GameData.Instance.PropsData[name] += num;
        }
        GameData.DateSave();
    }

    public static getPropByType(type: PROPS): number {
        const name: string = ZTool.GetEnumKeyByValue(PROPS, type);
        if (!GameData.Instance.PropsData[name]) {
            console.error(`没有该道具！`);
            return 0;
        } else {
            return GameData.Instance.PropsData[name];
        }
    }

    public static userPropByType(type: PROPS) {
        const name: string = ZTool.GetEnumKeyByValue(PROPS, type);

        if (!GameData.Instance.PropsData[name]) {
            // console.error(`没有该道具！请前往商店购买`);
            return;
        } else {
            GameData.Instance.PropsData[name]--;
        }
    }


    public static autoSave(time: number = 30) {
        //定时存档
        setInterval(() => {
            GameData.DateSave();
        }, time * 1000)
    }

}